package com.wfy.modules.openInterface.service;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.wfy.common.config.Global;
import com.wfy.common.entity.Result;
import com.wfy.common.entity.ResultGenerate;
import com.wfy.common.service.CrudService;
import com.wfy.common.service.ServiceException;
import com.wfy.common.util.DateUtils;
import com.wfy.common.util.JedisUtils;
import com.wfy.common.util.PageData;
import com.wfy.common.util.StringUtils;
import com.wfy.modules.openInterface.common.SensorStatusEnum;
import com.wfy.modules.openInterface.dao.DeviceInfoDao;
import com.wfy.modules.openInterface.entity.DeviceInfo;
import com.wfy.modules.openInterface.entity.SensorInfo;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.List;
import java.util.Map;
import java.util.Objects;

/**
 * Created with IntelliJ IDEA.
 * User: wangxindong
 * Date: 2017/9/27
 * Time: 13:44
 */
@Service(value = "deviceInfoService")
public class DeviceInfoService extends CrudService<DeviceInfoDao, DeviceInfo> {

    // ================================================================
    // Constants
    // ================================================================

    // ================================================================
    // Fields
    // ================================================================

    @Resource
    private DeviceInfoService deviceInfoService;

    @Resource
    private SensorInfoService sensorInfoService;


    // ================================================================
    // Constructors
    // ================================================================

    // ================================================================
    // Methods from/for super Interfaces or SuperClass
    // ================================================================

    // ================================================================
    // Public or Protected Methods
    // ================================================================

    public DeviceInfo getDevice(DeviceInfo deviceInfo) throws ServiceException {
        return dao.getDevice(deviceInfo);
    }

    public Result findDeviceSensorData(PageData pd) {
        String code = pd.getString("code");
        String token = pd.getString("token");
        DeviceInfo deviceInfo = new DeviceInfo();
        deviceInfo.setCode(code);

        deviceInfo = deviceInfoService.getDevice(deviceInfo);
        if (null == deviceInfo) {
            return ResultGenerate.getResult(Global.NO_DEVICE_MSG, Global.NO_DEVICE_CODE);
        }

        // 获取装置状态
        String deviceData = JedisUtils.hget(Global.DEFAULT_SENSOR_DATA_NAMESPACE, deviceInfo.getCode());
        if (null == deviceData) {
            deviceInfo.setStatus(SensorStatusEnum.Unknown.getMsg());
        } else {
            JSONObject deviceJson = JSON.parseObject(deviceData);
            deviceInfo.setStatus(getStatus(deviceJson));
        }

        SensorInfo sensorInfo = new SensorInfo();
        sensorInfo.setDeviceInfo(deviceInfo);
        sensorInfo.setToken(token);

        List<SensorInfo> dl = sensorInfoService.findList(sensorInfo);

        // 获取传感器实时数据
        for (SensorInfo s : dl) {
            String sensorCode = s.getCode();
            StringBuilder sb = new StringBuilder();
            sb.append(deviceInfo.getCode())
                    .append(Global.DEFAULT_DEVICE_DATA_SPLIT)
                    .append(sensorCode);
            String sensorJson = JedisUtils.hget(Global.DEFAULT_SENSOR_DATA_NAMESPACE, sb.toString());

            if (null == sensorJson) {
                s.setValue(null);
                s.setStatus(SensorStatusEnum.Unknown.getMsg());
            } else {
                JSONObject json = JSON.parseObject(sensorJson);
                Object value = getCurrentValue(json, s.getType());
                s.setValue(value);

                //状态
                String status = getStatus(json);
                s.setStatus(status);
                // 数据时间
                String dataTime = getDataTime(json);
                s.setDataTime(dataTime);
            }
            s.setCode(s.getRemarks());
        }
        deviceInfo.setSensorInfos(dl);
        return ResultGenerate.getSuccessResult(deviceInfo);
    }


    // ================================================================
    // Getter & Setter
    // ================================================================

    // ================================================================
    // Private Methods
    // ================================================================

    /**
     * 根据传感器type获取当前值
     *
     * @param json
     * @param type
     * @return
     */
    private Object getCurrentValue(JSONObject json, String type) {
        // 加速度
        if (StringUtils.isNotBlank(type) && Objects.equals(type, "7") || Objects.equals(type, "8")) {
            Map<String, String> result = json.getObject("realValue", Map.class);
            return result;
        }

        // gps
        if (StringUtils.isNotBlank(type) && Objects.equals(type, "15") || Objects.equals(type, "16")) {
            Map<String, String> result = json.getObject("realValue", Map.class);
            return result;
        }

        // 默认其他类型处理
        String value = json.getString("realValue");
        return value;
    }


    private String getStatus(JSONObject sensorInfo) {
        String result = null;

        boolean onLine = sensorInfo.getBoolean("onLine");
        if (!onLine) {
            result = SensorStatusEnum.Unknown.getMsg();
        } else {
            String status = sensorInfo.getString("status");
            if (null == status) {
                result = SensorStatusEnum.Unknown.getMsg();
            } else {
                result = SensorStatusEnum.getValueByKey(Integer.parseInt(status));
            }
            if (null == result) {
                result = SensorStatusEnum.Unknown.getMsg();
            }
        }
        return result;

    }

    private String getDataTime(JSONObject sensorInfo) {
        String redisDataTime = sensorInfo.getString("dataTime");
        return DateUtils.stampToDate(redisDataTime);
    }


    // ================================================================
    // Inner or Anonymous Class
    // ================================================================

    // ================================================================
    // Test Methods
    // ================================================================

}
